const sfc = require('@vue/compiler-sfc');
/**
 * vue单文件语法树解析
 */
exports.parseSfc = (code) => {
    const res = sfc.parse(
        code,
        {
            id: 'uid',
            filename: 'a.vue'
        }
    );
    return {
        template: {
            content: res.descriptor.template ? res.descriptor.template.content : "",
            attrs: res.descriptor.template ? res.descriptor.template.attrs : {},
            ast: res.descriptor.template ? res.descriptor.template.ast : {},
        },
        script: {
            content: res.descriptor.script ? res.descriptor.script.content : "",
            attrs: res.descriptor.script ? res.descriptor.script.attrs : {}
        },
        scriptSetup: {
            content: res.descriptor.scriptSetup ? res.descriptor.scriptSetup.content : "",
            attrs: res.descriptor.scriptSetup ? res.descriptor.scriptSetup.attrs : {}
        },
        styles: res.descriptor.styles.map(el => ({
            content: el.content,
            attrs: el.attrs
        }))
    }
}

/**
 * uniapp的template转化为web版的模板;TODO:FIXME:暂且用正则直接修改
 * @param {string} content 
 * @returns 
 */
exports.transUniTemplateToWeb = (content) => {
    content = content.replace(new RegExp('<view', "gm"), "<div")
    content = content.replace(new RegExp('</view', "gm"), "</div")
    return content
}

function traverseTree(tree, callback = () => { }, result = [], config = { childrenAlias: "children" }) {
    const traverseAllChild = (parentNode, children, result) => {
        let len = children.length
        let curNode = null
        for (let i = 0; i < len; i++) {
            curNode = children[i]
            callback(parentNode, curNode, result)
            if (Array.isArray(curNode[config["childrenAlias"]])) {
                traverseAllChild(parentNode, curNode[config["childrenAlias"]], result)
            }
        }

    }
    if (Array.isArray(tree)) {
        tree.forEach(el => {
            traverseAllChild(null, el.result)
        })
    } else if (Array.isArray(tree[config["childrenAlias"]])) {
        callback(null, [tree], result)
        traverseAllChild(tree, tree[config["childrenAlias"]], result)
    }
}
/**
 * 获取模板中使用easycomp的组件名
 * @param {object} ast 
 */
exports.getEasycomFromAst = (ast) => {
    const result = []
    const callback = (parentNode, curNode, result) => {
        if (curNode.type === 1) {
            if (curNode.tag.startsWith("gd-") || curNode.tag.startsWith("adv-") || curNode.tag.startsWith("scene-container-") || curNode.tag.startsWith("biz-") || curNode.tag.startsWith("uni-")) {
                !result.includes(curNode.tag) && result.push(curNode.tag)
            }
        }
    }
    traverseTree(ast, callback, result)
    return result
}

/**
 * 命名类型转换
 * 支持：Camel小驼峰、Pascal大驼峰、Snake下划线、Kebab中划线
 * @param {string} name 原变量名
 * @param {string} fromNamingRule 原变量命名规则
 * @param {string} toNamingRule 目标变量命名规则
 * */
function transName(name, fromNamingRule, toNamingRule) {
    // 对应命名类型的转换规则
    const NamingRules = {
        // 小驼峰
        'Camel': {
            // 把对应命名规则的命名转换成数组状态
            ArrayState: (name) => {
                return name.replace(/([A-Z])/g, '-$1').toLowerCase().split('-')
            },
            // 把数组状态转化成对应命名规则的命名
            TransToTargetNaming: (arrayState) => {
                let result = ''
                arrayState.forEach((el, idx) => {
                    if (idx === 0) {
                        result += el
                    } else {
                        result += el.replace(el[0], el[0].toUpperCase())
                    }
                })
                return result
            }
        },
        // 大驼峰
        'Pascal': {
            ArrayState: (name) => {
                name = name[0] ? name.replace(name[0], name[0].toUpperCase()) : '';
                return name.replace(/([A-Z])/g, '-$1').toLowerCase().split('-').splice(1)
            },
            TransToTargetNaming: (arrayState) => {
                let result = ''
                arrayState.forEach((el, idx) => {
                    result += el.replace(el[0], el[0].toUpperCase())
                })
                return result
            }
        },
        // 下划线
        'Snake': {
            ArrayState: (name) => {
                return name.toLowerCase().split('_')
            },
            TransToTargetNaming: (arrayState) => {
                const result = arrayState.join('_')
                return result
            }
        },
        // 中划线
        'Kebab': {
            ArrayState: (name) => {
                return name.toLowerCase().split('-')
            },
            TransToTargetNaming: (arrayState) => {
                const result = arrayState.join('-')
                return result
            }
        }
    }
    const arrayStateVal = NamingRules[fromNamingRule]['ArrayState'](name);
    const result = NamingRules[toNamingRule]['TransToTargetNaming'](arrayStateVal)
    return result
}

/**
 * 在script-setup中自动导入easycom组件
 * @param {Array} easycomList
 * @param {string} scriptSetupCode
 * "^gd-(.*)": "@uni_modules/gd-accbuild-core/components/gd-accbuild-ui/gd-ui/gd-$1/gd-$1.vue",
 * "^biz-(.*)": "@uni_modules/gd-accbuild-core/components/gd-accbuild-ui/biz-ui/biz-$1/pc/src/index.vue"
 */
exports.genImportFromEasycomp = (easycomList, scriptSetupCode, targetPlatform = "pc") => {
    easycomList.forEach(el => {
        let curEasycompReg = new RegExp();
        let willImport = ""
        if (el.startsWith("gd-")) {
            curEasycompReg = new RegExp(`/${el}/${el}.vue`)
            willImport = `import ${transName(el, "Kebab", "Pascal")} from "@gd-accbuild-ui/gd-ui/${el}/${el}.vue";\n`
        } else if (el.startsWith("adv-")) {
            curEasycompReg = new RegExp(`/${el}/${el}.vue`)
            willImport = `import ${transName(el, "Kebab", "Pascal")} from "@gd-accbuild-ui/adv-ui/${el}/${el}.vue";\n`
        }else if (el.startsWith("scene-container-")) {
            curEasycompReg = new RegExp(`/${el}/${el}.vue`)
            willImport = `import ${transName(el, "Kebab", "Pascal")} from "@gd-accbuild-ui/scene-container/${el}/${el}.vue";\n`
        } else if (el.startsWith("biz-")) {
            curEasycompReg = new RegExp(`/${el}/${targetPlatform}/src/index.vue`)
            willImport = `import ${transName(el, "Kebab", "Pascal")} from "@gd-accbuild-ui/biz-ui/${el}/${targetPlatform}/src/index.vue";\n`
        }/*  else if (el.startsWith("uni-")) {
            curEasycompReg = new RegExp(`@dcloudio/uni-ui/lib/${el}/${el}.vue`)
            willImport = `import ${transName(el, "Kebab", "Pascal")} from "@dcloudio/uni-ui/lib/${el}/${el}.vue";\n`
        } */
        if (!curEasycompReg.test(scriptSetupCode)) {
            scriptSetupCode = willImport + scriptSetupCode
        }
    })
    return scriptSetupCode
}



